package cn.hd01.thymeleaf;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.util.StringUtils;
import org.thymeleaf.Arguments;
import org.thymeleaf.Configuration;
import org.thymeleaf.dom.Element;
import org.thymeleaf.dom.Node;
import org.thymeleaf.dom.Text;
import org.thymeleaf.processor.attr.AbstractChildrenModifierAttrProcessor;
import org.thymeleaf.spring4.context.SpringWebContext;
import org.thymeleaf.standard.expression.IStandardExpression;
import org.thymeleaf.standard.expression.IStandardExpressionParser;
import org.thymeleaf.standard.expression.StandardExpressions;

import cn.hd01.common.BaseConstant.AuditStatus;
import cn.hd01.common.BaseConstant.CustomerType;
import cn.hd01.common.BaseConstant.IsBalance;
import cn.hd01.common.BaseConstant.backendType;
import cn.hd01.repository.entity.Permissions;
import cn.hd01.repository.entity.User;
import cn.hd01.service.COrderService;
import cn.hd01.service.CustomerService;
import cn.hd01.service.PermissionsService;
import cn.hd01.util.SpringContextUtil;
import cn.hd01.util.TreeNode;
import cn.hd01.web.util.WebHelper;

public class MenuProcessor extends AbstractChildrenModifierAttrProcessor {

	public static final String upgradDisMenu =  "待升级渠道商详情";
	public static final String notBalanceMenu =  "消费记录";
	
	public MenuProcessor() {
		super("menu");
	}

	@Override
	public int getPrecedence() {
		return 0;
	}

	@Override
	protected List<Node> getModifiedChildren(Arguments arguments, Element element, String attributeName) {
		String attributeValue = element.getAttributeValue(attributeName);
		Configuration configuration = arguments.getConfiguration();
		IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);
		IStandardExpression expression = parser.parseExpression(configuration, arguments, attributeValue);
		Integer role = (Integer) expression.execute(configuration, arguments);

		SpringWebContext context = (SpringWebContext) arguments.getContext();
		String basepath = context.getHttpServletRequest().getContextPath();
		String currpath = context.getHttpServletRequest().getRequestURI();
		String params = context.getHttpServletRequest().getQueryString();
		if(StringUtils.hasText(params)){
			currpath += "?" + params;
		}
		
		PermissionsService service = context.getApplicationContext().getBean(PermissionsService.class);
		TreeNode<Permissions> permissionsTree = service.findMenuByRoleId(role);

		List<Node> nodes = new ArrayList<Node>();
		int upgradeDisCount = 0;//customerService.countByTypeAndAuditStatus(CustomerType.CUSTOMER, AuditStatus.AUDIT_WAIT);
		int notBalanceCount = 0;
		
		User user = WebHelper.currentUser();
		CustomerService customerService = SpringContextUtil.getBean(CustomerService.class);
		COrderService cOrderService = SpringContextUtil.getBean(COrderService.class);
		if(backendType.ADMIN.equals(user.getType())){
			upgradeDisCount = customerService.countByTypeAndAuditStatus(CustomerType.CUSTOMER, AuditStatus.AUDIT_WAIT);
			notBalanceCount = cOrderService.countByIsBalance(IsBalance.BALANCE_WAIT);
		}else if(backendType.TEACHER.equals(user.getType())){
			upgradeDisCount = customerService.countByTypeAndAuditStatusAndServantId(CustomerType.CUSTOMER, AuditStatus.AUDIT_WAIT, user.getId());
			notBalanceCount = cOrderService.countByServantIdAndIsBalance(user.getId(), IsBalance.BALANCE_WAIT);
		}
		
		Map<String, String> paramsMap = new HashMap<String, String>();
		paramsMap.put("upgradeDisCount", String.valueOf(upgradeDisCount));
		paramsMap.put("notBalanceCount", String.valueOf(notBalanceCount));
		for (TreeNode<Permissions> node : permissionsTree.getChildren()) {
			
			nodes.add(build(node, basepath, currpath, paramsMap));
		}
		return nodes;
	}

	private Node build(TreeNode<Permissions> node, String basepath, String currpath, Map<String, String> paramsMap) {
		Permissions p = node.getData();
		
		String upgradeDisCount = paramsMap.get("upgradeDisCount");
		String notBalanceCount = paramsMap.get("notBalanceCount");
		if(p.getName().startsWith(notBalanceMenu)){
			p.setName(notBalanceMenu + "(" + notBalanceCount + ")");
		}else if(p.getName().startsWith(upgradDisMenu)){
			p.setName(upgradDisMenu + "(" + upgradeDisCount + ")");
		}
		
		Element container = new Element("li");
		Element a = new Element("a");
		
		String url = url(p.getUrl(), basepath);
		a.setAttribute("href", url);

		if(currpath.equals(url)){
			container.setAttribute("class", "active");
		}
		
		if (StringUtils.hasText(p.getImg())) {
			Element icon = new Element("i");
			icon.setAttribute("class", p.getImg());
			a.addChild(icon);
		}

		Element text = new Element("span");
		text.addChild(new Text(p.getName()));
		a.addChild(text);

		container.addChild(a);

		Element ul = new Element("ul");

		List<Node> childs = new ArrayList<Node>();
		for (TreeNode<Permissions> child : node.getChildren()) {
			childs.add(build(child, basepath, currpath, paramsMap));
		}

		if (!childs.isEmpty()) {
			//container.setAttribute("class", "active");
			ul.setChildren(childs);
			container.addChild(ul);
		}

		return container;
	}

	private String url(String menu, String basepath) {
		if (!StringUtils.hasText(menu)) {
			return "javascript:void(0);";
		}

		return basepath + (menu.startsWith("/") ? "" : "/") + menu;
	}

}
